/********************************************************************************
* @copyright  : Metanergy Technology R&D Co., Ltd
* @filename   : myg0025_divsqrt.h
* @brief      : DIVSQRT Initialization and Configuration functions
* @Author     : AE Team
*********************************************************************************/

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MYG0025_DIVSQRT_H
#define __MYG0025_DIVSQRT_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "myg0025.h"

/** @addtogroup DIVSQRT DIVSQRT
  * @{
  */

/** @defgroup DIVSQRT_Exported_Constants DIVSQRT_Exported_Constants
  * @{
  */

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/

#define DVSQ_BUSY_WAIT_EN                           1                                     /* If it is 1, it will judge and wait for DVSQ to be free before reading the DVSQ operation result register */

// DVSQ peripheral clock
#define RCC_AHBPeriph_DVSQ_CLK_Enable()             RCC->AHBENR |= RCC_AHBPeriph_DIVSQ     /* Enable the DVSQ peripheral clock */
#define RCC_AHBPeriph_DVSQ_CLK_Disable()            RCC->AHBENR &= ~RCC_AHBPeriph_DVSQ    /* Disable the DVSQ peripheral clock */

/* DVSQ Working state definition */
#define DVSQ_IDLE_NO_OPERATION                      ((uint32_t)0x00000000)                /* The accelerator is idle and has not performed a square root or division operation  */
#define DVSQ_IDLE_SQRT                              ((uint32_t)0x20000000)                /* The accelerator is idle and the last operation completed was the square root operation  */
#define DVSQ_IDLE_DIV                               ((uint32_t)0x40000000)                /* The accelerator is idle and the last operation completed is division */
#define DVSQ_BUSY_SQRT                              ((uint32_t)0xA0000000)                /* The accelerator is busy and performing a square root operation */
#define DVSQ_BUSY_DIV                               ((uint32_t)0xC0000000)                /* The accelerator is busy and is doing division */

/* Configure the startup mode of the DVSQ division operation */
#define DVSQ_EnableDivFastStart()                   DVSQ->CSR &= ~DVSQ_CSR_DFS         /* Enables the quick division function */
#define DVSQ_DisableDivFastStart()                  DVSQ->CSR |= DVSQ_CSR_DFS          /* Disables the quick division function */

/* Configures whether the DVSQ division is signed */
#define DVSQ_ConfigDivUnsigned()                    DVSQ->CSR |= DVSQ_CSR_UNSIGN_DIV   /* Configure the DVSQ to perform unsigned division mode */
#define DVSQ_ConfigDivSigned()                      DVSQ->CSR &= ~DVSQ_CSR_UNSIGN_DIV  /* Configure the DVSQ to perform signed division mode */

/* Configures whether the DVSQ division is signed */
#define DVSQ_ConfigSqrtPresHigh()                   DVSQ->CSR |= DVSQ_CSR_HPRESQRT    /* Configure DVSQ as high precision square operation mode */
#define DVSQ_ConfigSqrtPresNormal()                 DVSQ->CSR &= ~DVSQ_CSR_HPRESQRT    /* Configure DVSQ as norm precision square operation mode */

/* When DVSQ_CSR_DFS in THE CSR of DVSQ is 1, the software must start the division operation. When the bit is 0, the hardware automatically starts the division operation after the value is written into the divisor register   */
#define DVSQ_StartDivCalc()                         DVSQ->CSR |= DVSQ_CSR_DIV_SRT      /* Start division */

/* DVSQ busy status */
#define DVSQ_IsBusy()                               ((DVSQ->CSR & DVSQ_CSR_BUSY)? 1:0) /* Return '1' for busy; Return '0' for idle */

/* DVSQ waits idle */
#if (DVSQ_BUSY_WAIT_EN == 1)
#define DVSQ_Wait()                                 while(DVSQ_IsBusy())
#else
#define DVSQ_Wait()
#endif

/**
  * @}
  */

/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */

/** @defgroup DIVSQRT_Exported_Functions DIVSQRT_Exported_Functions
  * @{
  */

/*DIVSQRT API function interface */
void Dvsq_Init(void);
uint32_t Dvsq_Sqrt(uint32_t u32Radicand);
uint16_t Dvsq_Sqrt_H(uint32_t u32Radicand, uint16_t *fraction);
int32_t Dvsq_Divsion(int32_t i32Dividend, int32_t i32Divisor, int32_t *i32pRemainder);
uint32_t Dvsq_UDivsion(uint32_t u32Dividend, uint32_t u32Divisor, uint32_t *u32pRemainder);

/**
  * @}
  */

/**
  * @}
  */

#ifdef __cplusplus
}
#endif

#endif
